#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define N 5
pthread_mutex_t chopstick[N];
#define USE_SEQ
void *doit(void *arg)
{
	char p = *(char *)arg;
	int left, right;
	int phi = p - 'A';
	if (phi == 0) {
		left = 0;
		right = N-1;
	} else {
		left = phi - 1;
		right = phi;
	}

	while(1) {
		//sleep(rand()%10);
		usleep(3);
#ifdef USE_TRYLOCK
		if (pthread_mutex_trylock(&chopstick[left]))
			continue;
		printf("philosopher %c fetch chopstick %d\n", p, left+1);
		if (pthread_mutex_trylock(&chopstick[right])) {
			pthread_mutex_unlock(&chopstick[left]);
			continue;
		}
#elif defined(USE_SEQ)
		pthread_mutex_lock(&chopstick[left]);
		printf("philosopher %c fetch chopstick %d\n", p, left+1);
		pthread_mutex_lock(&chopstick[right]);
#endif
		printf("philosopher %c fetch chopstick %d\n", p, right+1);
		printf("philosopher %c is eating\n", p);
		usleep(3);
		//sleep(rand()%10);
		pthread_mutex_unlock(&chopstick[right]);
		pthread_mutex_unlock(&chopstick[left]);
	}
}
void main(void)
{
	pthread_t phi[N];
	char phi_name[N];
	int i;

	srand(time(NULL));

	for (i = 0; i < N; i++){
		phi_name[i] = i+'A';
		pthread_mutex_init(&chopstick[i], NULL);
	}

	for (i = 0; i < N; i++){
		pthread_create(&phi[i], NULL, doit, (void *)&phi_name[i]);
		printf("%c: 0x%x\n", phi_name[i], (unsigned int)phi[i]);
	}
	
	for (i = 0; i < N; i++){
		printf("0x%x\n", (unsigned int) phi[i]);
		pthread_join(phi[i], NULL);
	}
}


